#include "hc32_ddl.h"
//#include "algorithm_manage.h"
#include "bsp_i2s_slave.h"
#include "wm8731.h"

/*********************中断时间测量GPIO配置**************************/
#define INT_TIME_MEASURE_PORT           PortC
#define INT_TIME_MEASURE_PIN            Pin14

/**********************I2S MCU端接口配置***************************/
#define I2S_MCU_PORT                    PortB
#define I2S_MCU_WS_PIN                  Pin14
#define I2S_MCU_SD_PIN                  Pin12
#define I2S_MCU_SD_IN_PIN               Pin13
#define I2S_MCU_CK_PIN                  Pin15
#define I2S_MCU_MCK_PORT                PortC
#define I2S_MCU_MCK_PIN                 Pin13

#define I2S_MCU_FUNC_WS                 Func_I2s3_Ws
#define I2S_MCU_FUNC_CK                 Func_I2s3_Ck
#define I2S_MCU_FUNC_SDIN               Func_I2s3_Sdin
#define I2S_MCU_FUNC_SD                 Func_I2s3_Sd
#define I2S_MCU_CLOCK                   PWC_FCG1_PERIPH_I2S3


#define I2S_MCU_CH                      M4_I2S3
#define I2S_MCU_TX_DMA_UNIT             M4_DMA2
#define I2S_MCU_TX_DMA_CH               DmaCh1
#define I2S_MCU_TX_DMA_CLK              (PWC_FCG0_PERIPH_DMA2)
#define I2S_MCU_TX_DMA_TRG              (EVT_I2S3_TXIRQOUT)

#define I2S_MCU_RX_DMA_UNIT             M4_DMA2
#define I2S_MCU_RX_DMA_CH               DmaCh0
#define I2S_MCU_RX_DMA_CLK              (PWC_FCG0_PERIPH_DMA2)
#define I2S_MCU_RX_DMA_TRG              (EVT_I2S3_RXIRQOUT)
/**********************I2S CODEC端接口配置***************************/
#define I2S_CODEC_PORT                  PortA
#define I2S_CODEC_WS_PIN                Pin00
#define I2S_CODEC_SD_PIN                Pin15
#define I2S_CODEC_SD_IN_PIN             Pin08
#define I2S_CODEC_CK_PIN                Pin04
#define I2S_CODEC_MCK_PORT              PortB
#define I2S_CODEC_MCK_PIN               Pin02

#define I2S_CODEC_FUNC_WS               Func_I2s1_Ws
#define I2S_CODEC_FUNC_CK               Func_I2s1_Ck
#define I2S_CODEC_FUNC_SDIN             Func_I2s1_Sdin
#define I2S_CODEC_FUNC_SD               Func_I2s1_Sd
#define I2S_CODEC_CLOCK                 PWC_FCG1_PERIPH_I2S1


#define I2S_CODEC_CH                    M4_I2S1
#define I2S_CODEC_TX_DMA_UNIT           M4_DMA1
#define I2S_CODEC_TX_DMA_CH             DmaCh1
#define I2S_CODEC_TX_DMA_CLK            (PWC_FCG0_PERIPH_DMA1)
#define I2S_CODEC_TX_DMA_TRG            (EVT_I2S1_TXIRQOUT)

#define I2S_CODEC_RX_DMA_UNIT           M4_DMA1
#define I2S_CODEC_RX_DMA_CH             DmaCh0
#define I2S_CODEC_RX_DMA_CLK            (PWC_FCG0_PERIPH_DMA1)
#define I2S_CODEC_RX_DMA_TRG            (EVT_I2S1_RXIRQOUT)

#define I2S_MCU_BUFF_SIZE               1024
#define I2S_MCU_BUFF_NUM                2

#define I2S_CODEC_BUFF_SIZE             1024
#define I2S_CODEC_BUFF_NUM              2

uint32_t i2s_mcu_tx_buff[I2S_MCU_BUFF_NUM][I2S_MCU_BUFF_SIZE];
uint32_t i2s_mcu_rx_buff[I2S_MCU_BUFF_NUM][I2S_MCU_BUFF_SIZE];

uint32_t i2s_codec_tx_buff[I2S_CODEC_BUFF_NUM][I2S_CODEC_BUFF_SIZE];
uint32_t i2s_codec_rx_buff[I2S_CODEC_BUFF_NUM][I2S_CODEC_BUFF_SIZE];

static volatile stc_dma_llp_descriptor_t stc_llp_dma_mcu_rx[I2S_MCU_BUFF_NUM];
static volatile stc_dma_llp_descriptor_t stc_llp_dma_mcu_tx[I2S_MCU_BUFF_NUM];

static volatile stc_dma_llp_descriptor_t stc_llp_dma_codec_rx[I2S_CODEC_BUFF_NUM];
static volatile stc_dma_llp_descriptor_t stc_llp_dma_codec_tx[I2S_CODEC_BUFF_NUM];

static bool flag_ab_codec = 0;
static bool flag_ab_mcu = 0;

/**************************************算法运行时间检测**************************************************************/
static void bsp_i2s_measure_gpio(void)
{
    stc_port_init_t stcPortInit;
    /*initiallize LED port*/
    MEM_ZERO_STRUCT(stcPortInit);

    stcPortInit.enPinMode = Pin_Mode_Out;
    stcPortInit.enExInt = Enable;
    stcPortInit.enPullUp = Enable;

    /* LED0 Port/Pin initialization */
    PORT_Init(INT_TIME_MEASURE_PORT, INT_TIME_MEASURE_PIN, &stcPortInit);
    PORT_Init(INT_TIME_MEASURE_PORT, Pin15, &stcPortInit);
    PORT_ResetBits(INT_TIME_MEASURE_PORT, Pin15);
}



/******************************************对接MCU端的I2S配置***********************************************/
static void bsp_i2s_mcu_gpio_init(void)
{
    stc_port_init_t stcPortIni;

    /* Initialize i2s port for codec wm8731 recorder function */
    MEM_ZERO_STRUCT(stcPortIni);
    stcPortIni.enPullUp = Enable;
    stcPortIni.enPinDrv = Pin_Drv_H;
    //  PORT_Init(I2S1_MCLK_PORT,   I2S1_MCLK_PIN, &stcPortIni);    /*I2S_MCLK*/
    PORT_Init(I2S_MCU_PORT,  I2S_MCU_WS_PIN,     &stcPortIni);
    PORT_Init(I2S_MCU_PORT,  I2S_MCU_CK_PIN,     &stcPortIni);
    PORT_Init(I2S_MCU_PORT,  I2S_MCU_SD_IN_PIN,  &stcPortIni);
    PORT_Init(I2S_MCU_PORT,  I2S_MCU_SD_PIN,     &stcPortIni);

    //  PORT_SetFunc(I2S1_MCLK_PORT,    I2S1_MCLK_PIN,  Func_I2s, Disable);      /*I2S_MCLK*/
    PORT_SetFunc(I2S_MCU_PORT,   I2S_MCU_WS_PIN,   I2S_MCU_FUNC_WS,   Disable);     /*I2S_LRCLK*/
    PORT_SetFunc(I2S_MCU_PORT,   I2S_MCU_CK_PIN,   I2S_MCU_FUNC_CK,   Disable);     /*I2S_BCLK*/
    PORT_SetFunc(I2S_MCU_PORT,   I2S_MCU_SD_IN_PIN,I2S_MCU_FUNC_SDIN, Disable);     /*I2S_DIN*/
    PORT_SetFunc(I2S_MCU_PORT,   I2S_MCU_SD_PIN,   I2S_MCU_FUNC_SD,   Disable);     /*I2S_DOUT*/

    PORT_Init(I2S_MCU_MCK_PORT, I2S_MCU_MCK_PIN, &stcPortIni);
    PORT_SetFunc(I2S_MCU_MCK_PORT, I2S_MCU_MCK_PIN, Func_I2s, Disable);

    /* Enable I2S Peripheral*/
    PWC_Fcg1PeriphClockCmd(I2S_MCU_CLOCK, Enable);

    /* Config clock source for i2s */
    CLK_SetI2sClkSource(I2S_MCU_CH, ClkPeriSrcMpllp);
}



static void bsp_i2s_mcu_rx_dma_config(uint32_t destadd[][I2S_MCU_BUFF_SIZE])
{
    uint8_t i;
    stc_dma_config_t stcDmaCfg;
    stc_irq_regi_conf_t stcIrqRegiConf;
    MEM_ZERO_STRUCT(stcDmaCfg);
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    DMA_ChannelCmd(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH,Disable);
    DMA_DeInit(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH);
    PWC_Fcg0PeriphClockCmd(I2S_MCU_RX_DMA_CLK,Disable);

    /* Set data block size. */
    stcDmaCfg.u16BlockSize = 1;  //uint16
    /* Set transfer count. */
    stcDmaCfg.u16TransferCnt = I2S_MCU_BUFF_SIZE;
    /* Set source & destination address. */
    stcDmaCfg.u32SrcAddr = (uint32_t)(&I2S_MCU_CH->RXBUF);
    stcDmaCfg.u32DesAddr = (uint32_t)destadd[0];//(&i2s_codec_tx_buff[0][0]);//

    /* Disable linked list transfer. */
    stcDmaCfg.stcDmaChCfg.enLlpEn = Disable;
    /* Enable repeat function. */
    stcDmaCfg.stcDmaChCfg.enSrcRptEn = Disable;
    stcDmaCfg.stcDmaChCfg.enDesRptEn = Disable;
    /* Set source & destination address mode. */
    stcDmaCfg.stcDmaChCfg.enSrcInc = AddressFix;
    stcDmaCfg.stcDmaChCfg.enDesInc = AddressIncrease;
    /* Enable interrup. */
    stcDmaCfg.stcDmaChCfg.enIntEn = Enable;
    /* Set data width 32bit. */
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma32Bit;

    for(i=0; i<I2S_MCU_BUFF_NUM; i++) {
        stc_llp_dma_mcu_rx[i].SARx = (uint32_t)(&I2S_MCU_CH->RXBUF);
        stc_llp_dma_mcu_rx[i].DARx = (uint32_t)destadd[i];//(&i2s_codec_tx_buff[i][0]);//
        stc_llp_dma_mcu_rx[i].DTCTLx_f.CNT = I2S_MCU_BUFF_SIZE;//单个链表的大小
        stc_llp_dma_mcu_rx[i].DTCTLx_f.BLKSIZE = 1u;
        if(i==(I2S_MCU_BUFF_NUM-1)) { //是否最后一个链表，最后一个链表链接回第一个链表，作为回环
            stc_llp_dma_mcu_rx[i].LLPx = (uint32_t)(&stc_llp_dma_mcu_rx[0]);
        } else {
            stc_llp_dma_mcu_rx[i].LLPx = (uint32_t)(&stc_llp_dma_mcu_rx[i+1]);
        }
        stc_llp_dma_mcu_rx[i].CHxCTL_f.DRPTEN = Disable;//使能目标地址重置
        stc_llp_dma_mcu_rx[i].CHxCTL_f.SRPTEN = Disable;//取消源地址重置
        stc_llp_dma_mcu_rx[i].RPTx_f.DRPT = 0;
        stc_llp_dma_mcu_rx[i].RPTx_f.SRPT = 0;
        stc_llp_dma_mcu_rx[i].CHxCTL_f.SINC = AddressFix;//源地址自增
        stc_llp_dma_mcu_rx[i].CHxCTL_f.DINC = AddressIncrease;//目标地址自增
        stc_llp_dma_mcu_rx[i].CHxCTL_f.HSIZE = Dma32Bit;
        stc_llp_dma_mcu_rx[i].CHxCTL_f.LLPEN = Enable;
        stc_llp_dma_mcu_rx[i].CHxCTL_f.LLPRUN = LlpRunNow;

        stc_llp_dma_mcu_rx[i].CHxCTL_f.DNSEQEN = Disable;
        stc_llp_dma_mcu_rx[i].CHxCTL_f.SNSEQEN = Disable;
        stc_llp_dma_mcu_rx[i].CHxCTL_f.IE = Enable;
        stc_llp_dma_mcu_rx[i].DNSEQCTLx_f.DNSCNT = 1;
        stc_llp_dma_mcu_rx[i].DNSEQCTLx_f.DOFFSET = 1;
    }
    stcDmaCfg.stcDmaChCfg.enLlpEn = Enable;
    stcDmaCfg.stcDmaChCfg.enLlpMd = LlpRunNow;
    stcDmaCfg.u32DmaLlp = (uint32_t)(&stc_llp_dma_mcu_rx[0]);//指向第一个链表
    /* Enable DMA clock. */
    PWC_Fcg0PeriphClockCmd(I2S_MCU_RX_DMA_CLK,Enable);

    /* Enable DMA1. */
//   DMA_Cmd(I2S_MCU_RX_DMA_UNIT,Enable);
    /* Initialize DMA. */
    DMA_InitChannel(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH, &stcDmaCfg);
    /* Enable DMA1 channel0. */
    DMA_ChannelCmd(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH,Enable);

    DMA_ClearIrqFlag(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH,TrnCpltIrq);

    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);
    DMA_SetTriggerSrc(I2S_MCU_RX_DMA_UNIT, I2S_MCU_RX_DMA_CH, I2S_MCU_RX_DMA_TRG);
}

static void bsp_i2s_mcu_tx_dma_config(uint32_t destadd[][I2S_MCU_BUFF_SIZE])
{
    uint8_t i;
    stc_dma_config_t stcDmaCfg;
    stc_irq_regi_conf_t stcIrqRegiConf;
    MEM_ZERO_STRUCT(stcDmaCfg);
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    DMA_ChannelCmd(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH, Disable);
    DMA_DeInit(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH);

    /* Set data block size. */
    stcDmaCfg.u16BlockSize = 1;  //uint16
    stcDmaCfg.u16TransferCnt = 1;
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma32Bit;

    for(i=0; i<I2S_MCU_BUFF_NUM; i++) {
        stc_llp_dma_mcu_tx[i].SARx = (uint32_t)destadd[i];//(&i2s_mcu_tx_buff[i]);
        stc_llp_dma_mcu_tx[i].DARx = (uint32_t)(&I2S_MCU_CH->TXBUF);
        stc_llp_dma_mcu_tx[i].DTCTLx_f.CNT = I2S_MCU_BUFF_SIZE;
        stc_llp_dma_mcu_tx[i].DTCTLx_f.BLKSIZE = 1u;
        if(i == (I2S_MCU_BUFF_NUM - 1)) {
            stc_llp_dma_mcu_tx[i].LLPx = (uint32_t)(&stc_llp_dma_mcu_tx[0]);
        } else {
            stc_llp_dma_mcu_tx[i].LLPx = (uint32_t)(&stc_llp_dma_mcu_tx[i+1]);
        }
        stc_llp_dma_mcu_tx[i].CHxCTL_f.DRPTEN = Disable;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.SRPTEN = Disable;
        stc_llp_dma_mcu_tx[i].RPTx_f.DRPT = 0;
        stc_llp_dma_mcu_tx[i].RPTx_f.SRPT = 0;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.SINC = AddressIncrease;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.DINC = AddressFix;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.HSIZE = Dma32Bit;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.LLPEN = Enable;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.LLPRUN = LlpRunNow;

        stc_llp_dma_mcu_tx[i].CHxCTL_f.DNSEQEN = Disable;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.SNSEQEN = Disable;
        stc_llp_dma_mcu_tx[i].CHxCTL_f.IE = Enable;
        stc_llp_dma_mcu_tx[i].DNSEQCTLx_f.DNSCNT = 1;
        stc_llp_dma_mcu_tx[i].DNSEQCTLx_f.DOFFSET = 1;
    }
    stcDmaCfg.stcDmaChCfg.enLlpEn = Enable;
    stcDmaCfg.stcDmaChCfg.enLlpMd = LlpRunNow;
    stcDmaCfg.u32DmaLlp = (uint32_t)(&stc_llp_dma_mcu_tx[0]);
    /* Enable DMA clock. */
    PWC_Fcg0PeriphClockCmd(I2S_MCU_TX_DMA_CLK,Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);

    /* Enable DMA1. */
    //  DMA_Cmd(I2S_MCU_TX_DMA_UNIT,Enable);
    /* Initialize DMA. */
    DMA_InitChannel(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH, &stcDmaCfg);
    DMA_SetTriggerSrc(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH, I2S_MCU_TX_DMA_TRG);
    /* Enable DMA1 channel0. */
    DMA_ChannelCmd(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH,Enable);

    DMA_ClearIrqFlag(I2S_MCU_TX_DMA_UNIT, I2S_MCU_TX_DMA_CH, TrnCpltIrq);
//
//    stcIrqRegiConf.enIntSrc = INT_DMA1_BTC0;
//    stcIrqRegiConf.enIRQn = Int008_IRQn;
//    stcIrqRegiConf.pfnCallback =  REC_BTC0_CALLBACK;
//
//    enIrqRegistration(&stcIrqRegiConf);
//  NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);//Enable Interrupt
}

static uint32_t bsp_i2s_get_clk_freq(M4_I2S_TypeDef* pstcI2sReg)
{
    en_clk_peri_source_t enSrc = ClkPeriSrcPclk;
    uint32_t u32Freq = 0ul;
    stc_clk_freq_t stcClkFreq;
    stc_pll_clk_freq_t stcPllClkFreq;

    /* Check parameters */
    if(NULL != pstcI2sReg) {
        enSrc = CLK_GetI2sClkSource(pstcI2sReg);
        CLK_GetClockFreq(&stcClkFreq);
        CLK_GetPllClockFreq(&stcPllClkFreq);
        switch(enSrc) {
            case ClkPeriSrcPclk:
                u32Freq = stcClkFreq.pclk3Freq;
                break;
            case ClkPeriSrcMpllp:
                u32Freq = stcPllClkFreq.mpllp;
                break;
            case ClkPeriSrcMpllq:
                u32Freq = stcPllClkFreq.mpllq;
                break;
            case ClkPeriSrcMpllr:
                u32Freq = stcPllClkFreq.mpllr;
                break;
            case ClkPeriSrcUpllp:
                u32Freq = stcPllClkFreq.upllp;
                break;
            case ClkPeriSrcUpllq:
                u32Freq = stcPllClkFreq.upllq;
                break;
            case ClkPeriSrcUpllr:
                u32Freq = stcPllClkFreq.upllr;
                break;
            default:
                break;
        }
    }
    return u32Freq;
}
void i2s_mcu_tx_callback(void)
{
    static uint8_t i2s_mcu_tx_flag = 0;

    i2s_mcu_tx_flag = !i2s_mcu_tx_flag;
    if(i2s_mcu_tx_flag) {
    } else {
    }
}

void i2s_mcu_rx_callback(void)
{
    uint16_t i;

    flag_ab_mcu = !flag_ab_mcu;


    PORT_SetBits(INT_TIME_MEASURE_PORT, INT_TIME_MEASURE_PIN);
    if(flag_ab_mcu) {
        for(i = 0; i < I2S_CODEC_BUFF_SIZE; i++) {
            i2s_codec_tx_buff[0][i] = i2s_mcu_rx_buff[0][i];
        }
//        algorithm_run(i2s_codec_tx_buff[0], i2s_codec_tx_buff[0], I2S_CODEC_BUFF_SIZE);

    } else {
        for(i = 0; i < I2S_CODEC_BUFF_SIZE; i++) {
            i2s_codec_tx_buff[1][i] = i2s_mcu_rx_buff[1][i];
        }
//        algorithm_run(i2s_codec_tx_buff[1],i2s_codec_tx_buff[1], I2S_CODEC_BUFF_SIZE);
    }

    PORT_ResetBits(INT_TIME_MEASURE_PORT, INT_TIME_MEASURE_PIN);
}

void bsp_i2s_mcu_tx_timer_cfg(void)
{
    stc_timera_base_init_t stcTimeraInit;
    stc_irq_regi_conf_t stcIrqRegiConf;
    stc_timera_orthogonal_coding_init_t Hw_Count_Trg_Cfg;
    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcTimeraInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(Hw_Count_Trg_Cfg);

    /* Configuration peripheral clock */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIMA3, Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);

    /* Configuration TIMERA compare pin */

    /* Configuration timera unit 1 base structure */
    stcTimeraInit.enClkDiv = TimeraPclkDiv1;
    stcTimeraInit.enCntMode = TimeraCountModeSawtoothWave;
    stcTimeraInit.enCntDir = TimeraCountDirUp;
    stcTimeraInit.enSyncStartupEn = Disable;
    stcTimeraInit.u16PeriodVal = I2S_MCU_BUFF_SIZE-2;        //freq: 100Hz
    TIMERA_BaseInit(M4_TMRA3, &stcTimeraInit);


    /* Enable period count interrupt */
    TIMERA_IrqCmd(M4_TMRA3, TimeraIrqOverflow, Enable);
    /* Interrupt of timera unit 1 */
    stcIrqRegiConf.enIntSrc = INT_TMRA3_OVF;
    stcIrqRegiConf.enIRQn = Int013_IRQn;
    stcIrqRegiConf.pfnCallback = i2s_mcu_tx_callback;
    enIrqRegistration(&stcIrqRegiConf);
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_13);
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    TIMERA_SetCountTriggerSrc(I2S_MCU_TX_DMA_TRG);

    Hw_Count_Trg_Cfg.enIncSpecifyEventTriggerEn = Enable;
    TIMERA_OrthogonalCodingInit(M4_TMRA3,&Hw_Count_Trg_Cfg);
    M4_TMRA3->BCSTR_f.START = Enable;
}

static void bsp_i2s_mcu_rx_timer_cfg(void)
{
    stc_timera_base_init_t stcTimeraInit;
    stc_irq_regi_conf_t stcIrqRegiConf;
    stc_timera_orthogonal_coding_init_t Hw_Count_Trg_Cfg;
    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcTimeraInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(Hw_Count_Trg_Cfg);

    /* Configuration peripheral clock */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIMA4, Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);

    TIMERA_IrqCmd(M4_TMRA4, TimeraIrqOverflow, Disable);
    TIMERA_DeInit(M4_TMRA4);

    /* Configuration TIMERA compare pin */

    /* Configuration timera unit 1 base structure */
    stcTimeraInit.enClkDiv = TimeraPclkDiv1;
    stcTimeraInit.enCntMode = TimeraCountModeSawtoothWave;
    stcTimeraInit.enCntDir = TimeraCountDirUp;
    stcTimeraInit.enSyncStartupEn = Disable;
    stcTimeraInit.u16PeriodVal = I2S_MCU_BUFF_SIZE-2;        //freq: 100Hz
    TIMERA_BaseInit(M4_TMRA4, &stcTimeraInit);


    /* Enable period count interrupt */
    TIMERA_IrqCmd(M4_TMRA4, TimeraIrqOverflow, Enable);
    /* Interrupt of timera unit 1 */
    stcIrqRegiConf.enIntSrc = INT_TMRA4_OVF;
    stcIrqRegiConf.enIRQn = Int014_IRQn;
    stcIrqRegiConf.pfnCallback = i2s_mcu_rx_callback;
    enIrqRegistration(&stcIrqRegiConf);
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_15);
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    TIMERA_SetCountTriggerSrc(I2S_MCU_RX_DMA_TRG);

    Hw_Count_Trg_Cfg.enIncSpecifyEventTriggerEn = Enable;
    TIMERA_OrthogonalCodingInit(M4_TMRA4,&Hw_Count_Trg_Cfg);
    M4_TMRA4->BCSTR_f.START = Enable;
}

static void bsp_i2s_mcu_cfg_init(uint32_t samp_rate, uint8_t samp_bit)
{
    stc_i2s_config_t stcI2sCfg;

    MEM_ZERO_STRUCT(stcI2sCfg);
    I2s_DeInit(I2S_MCU_CH);
    stcI2sCfg.u32I2sInterClkFreq = bsp_i2s_get_clk_freq(I2S_MCU_CH);
    stcI2sCfg.enStandrad = Std_Philips;
    stcI2sCfg.enMode = I2sMaster;
    stcI2sCfg.enChanelLen = I2s_ChLen_32Bit;
    stcI2sCfg.enDataBits = (en_i2s_data_len_t)samp_bit;
    stcI2sCfg.u32AudioFreq = samp_rate;
    stcI2sCfg.enMcoOutEn = Enable;
    stcI2sCfg.enExckEn = Disable;
    stcI2sCfg.enFullDuplexMode = I2s_FullDuplex;

    I2s_Init(I2S_MCU_CH, &stcI2sCfg);
}


/******************************************对接CODEC端的I2S配置***********************************************/
static void bsp_i2s_codec_gpio_init(void)
{
    stc_port_init_t stcPortIni;

    /* Initialize i2s port for codec wm8731 recorder function */
    MEM_ZERO_STRUCT(stcPortIni);
    stcPortIni.enPullUp = Enable;
    stcPortIni.enPinDrv = Pin_Drv_H;
    //  PORT_Init(I2S1_MCLK_PORT,   I2S1_MCLK_PIN, &stcPortIni);    /*I2S_MCLK*/
    PORT_Init(I2S_CODEC_PORT,  I2S_CODEC_WS_PIN,     &stcPortIni);
    PORT_Init(I2S_CODEC_PORT,  I2S_CODEC_CK_PIN,     &stcPortIni);
    PORT_Init(I2S_CODEC_PORT,  I2S_CODEC_SD_IN_PIN,  &stcPortIni);
    PORT_Init(I2S_CODEC_PORT,  I2S_CODEC_SD_PIN,     &stcPortIni);

    //  PORT_SetFunc(I2S1_MCLK_PORT,    I2S1_MCLK_PIN,  Func_I2s, Disable);      /*I2S_MCLK*/
    PORT_SetFunc(I2S_CODEC_PORT,   I2S_CODEC_WS_PIN,   I2S_CODEC_FUNC_WS,   Disable);     /*I2S_LRCLK*/
    PORT_SetFunc(I2S_CODEC_PORT,   I2S_CODEC_CK_PIN,   I2S_CODEC_FUNC_CK,   Disable);     /*I2S_BCLK*/
    PORT_SetFunc(I2S_CODEC_PORT,   I2S_CODEC_SD_IN_PIN,I2S_CODEC_FUNC_SDIN, Disable);     /*I2S_DIN*/
    PORT_SetFunc(I2S_CODEC_PORT,   I2S_CODEC_SD_PIN,   I2S_CODEC_FUNC_SD,   Disable);     /*I2S_DOUT*/

    //PORT_Init(I2S_CODEC_MCK_PORT, I2S_CODEC_MCK_PIN, &stcPortIni);
    //PORT_SetFunc(I2S_CODEC_MCK_PORT, I2S_CODEC_MCK_PIN, Func_I2s, Disable);

    /* Enable I2S Peripheral*/
    PWC_Fcg1PeriphClockCmd(I2S_CODEC_CLOCK, Enable);

    /* Config clock source for i2s */
    CLK_SetI2sClkSource(I2S_CODEC_CH, ClkPeriSrcMpllp);
}

static void bsp_i2s_codec_rx_dma_config(uint32_t destadd[][I2S_MCU_BUFF_SIZE])
{
    uint8_t i;
    stc_dma_config_t stcDmaCfg;
    stc_irq_regi_conf_t stcIrqRegiConf;
    MEM_ZERO_STRUCT(stcDmaCfg);
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    DMA_ChannelCmd(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH,Disable);
    DMA_DeInit(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH);

    /* Set data block size. */
    stcDmaCfg.u16BlockSize = 1;  //uint16
    /* Set transfer count. */
    stcDmaCfg.u16TransferCnt = I2S_CODEC_BUFF_SIZE;
    /* Set source & destination address. */
    stcDmaCfg.u32SrcAddr = (uint32_t)(&I2S_CODEC_CH->RXBUF);
    stcDmaCfg.u32DesAddr = (uint32_t)destadd[0];//(&i2s_codec_rx_buff[0][0]);

    /* Disable linked list transfer. */
    stcDmaCfg.stcDmaChCfg.enLlpEn = Disable;
    /* Enable repeat function. */
    stcDmaCfg.stcDmaChCfg.enSrcRptEn = Disable;
    stcDmaCfg.stcDmaChCfg.enDesRptEn = Disable;
    /* Set source & destination address mode. */
    stcDmaCfg.stcDmaChCfg.enSrcInc = AddressFix;
    stcDmaCfg.stcDmaChCfg.enDesInc = AddressIncrease;
    /* Enable interrup. */
    stcDmaCfg.stcDmaChCfg.enIntEn = Enable;
    /* Set data width 32bit. */
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma32Bit;

    for(i=0; i<I2S_CODEC_BUFF_NUM; i++) {
        stc_llp_dma_codec_rx[i].SARx = (uint32_t)(&I2S_CODEC_CH->RXBUF);
        stc_llp_dma_codec_rx[i].DARx = (uint32_t)destadd[i];//(&i2s_codec_rx_buff[i][0]);
        stc_llp_dma_codec_rx[i].DTCTLx_f.CNT = I2S_CODEC_BUFF_SIZE;//单个链表的大小
        stc_llp_dma_codec_rx[i].DTCTLx_f.BLKSIZE = 1u;
        if(i==(I2S_CODEC_BUFF_NUM-1)) { //是否最后一个链表，最后一个链表链接回第一个链表，作为回环
            stc_llp_dma_codec_rx[i].LLPx = (uint32_t)(&stc_llp_dma_codec_rx[0]);
        } else {
            stc_llp_dma_codec_rx[i].LLPx = (uint32_t)(&stc_llp_dma_codec_rx[i+1]);
        }
        stc_llp_dma_codec_rx[i].CHxCTL_f.DRPTEN = Disable;//使能目标地址重置
        stc_llp_dma_codec_rx[i].CHxCTL_f.SRPTEN = Disable;//取消源地址重置
        stc_llp_dma_codec_rx[i].RPTx_f.DRPT = 0;
        stc_llp_dma_codec_rx[i].RPTx_f.SRPT = 0;
        stc_llp_dma_codec_rx[i].CHxCTL_f.SINC = AddressFix;//源地址自增
        stc_llp_dma_codec_rx[i].CHxCTL_f.DINC = AddressIncrease;//目标地址自增
        stc_llp_dma_codec_rx[i].CHxCTL_f.HSIZE = Dma32Bit;
        stc_llp_dma_codec_rx[i].CHxCTL_f.LLPEN = Enable;
        stc_llp_dma_codec_rx[i].CHxCTL_f.LLPRUN = LlpRunNow;

        stc_llp_dma_codec_rx[i].CHxCTL_f.DNSEQEN = Disable;
        stc_llp_dma_codec_rx[i].CHxCTL_f.SNSEQEN = Disable;
        stc_llp_dma_codec_rx[i].CHxCTL_f.IE = Enable;
        stc_llp_dma_codec_rx[i].DNSEQCTLx_f.DNSCNT = 1;
        stc_llp_dma_codec_rx[i].DNSEQCTLx_f.DOFFSET = 1;
    }
    stcDmaCfg.stcDmaChCfg.enLlpEn = Enable;
    stcDmaCfg.stcDmaChCfg.enLlpMd = LlpRunNow;
    stcDmaCfg.u32DmaLlp = (uint32_t)(&stc_llp_dma_codec_rx[0]);//指向第一个链表
    /* Enable DMA clock. */
    PWC_Fcg0PeriphClockCmd(I2S_CODEC_RX_DMA_CLK,Enable);

    /* Enable DMA1. */
//   DMA_Cmd(I2S_CODEC_RX_DMA_UNIT,Enable);
    /* Initialize DMA. */
    DMA_InitChannel(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH, &stcDmaCfg);
    /* Enable DMA1 channel0. */
    DMA_ChannelCmd(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH,Enable);

    DMA_ClearIrqFlag(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH,TrnCpltIrq);

    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);
    DMA_SetTriggerSrc(I2S_CODEC_RX_DMA_UNIT, I2S_CODEC_RX_DMA_CH, I2S_CODEC_RX_DMA_TRG);
}

static void bsp_i2s_codec_tx_dma_config(uint32_t destadd[][I2S_MCU_BUFF_SIZE])
{
    uint8_t i;
    stc_dma_config_t stcDmaCfg;
    stc_irq_regi_conf_t stcIrqRegiConf;
    MEM_ZERO_STRUCT(stcDmaCfg);
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    DMA_ChannelCmd(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH, Disable);
    DMA_DeInit(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH);

    /* Set data block size. */
    stcDmaCfg.u16BlockSize = 1;  //uint16
    stcDmaCfg.u16TransferCnt = 1;
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma32Bit;

    for(i=0; i<I2S_CODEC_BUFF_NUM; i++) {
        stc_llp_dma_codec_tx[i].SARx = (uint32_t)destadd[i];//(&i2s_codec_tx_buff[i]);
        stc_llp_dma_codec_tx[i].DARx = (uint32_t)(&I2S_CODEC_CH->TXBUF);
        stc_llp_dma_codec_tx[i].DTCTLx_f.CNT = I2S_CODEC_BUFF_SIZE;
        stc_llp_dma_codec_tx[i].DTCTLx_f.BLKSIZE = 1u;
        if(i == (I2S_CODEC_BUFF_NUM - 1)) {
            stc_llp_dma_codec_tx[i].LLPx = (uint32_t)(&stc_llp_dma_codec_tx[0]);
        } else {
            stc_llp_dma_codec_tx[i].LLPx = (uint32_t)(&stc_llp_dma_codec_tx[i+1]);
        }
        stc_llp_dma_codec_tx[i].CHxCTL_f.DRPTEN = Disable;
        stc_llp_dma_codec_tx[i].CHxCTL_f.SRPTEN = Disable;
        stc_llp_dma_codec_tx[i].RPTx_f.DRPT = 0;
        stc_llp_dma_codec_tx[i].RPTx_f.SRPT = 0;
        stc_llp_dma_codec_tx[i].CHxCTL_f.SINC = AddressIncrease;
        stc_llp_dma_codec_tx[i].CHxCTL_f.DINC = AddressFix;
        stc_llp_dma_codec_tx[i].CHxCTL_f.HSIZE = Dma32Bit;
        stc_llp_dma_codec_tx[i].CHxCTL_f.LLPEN = Enable;
        stc_llp_dma_codec_tx[i].CHxCTL_f.LLPRUN = LlpRunNow;

        stc_llp_dma_codec_tx[i].CHxCTL_f.DNSEQEN = Disable;
        stc_llp_dma_codec_tx[i].CHxCTL_f.SNSEQEN = Disable;
        stc_llp_dma_codec_tx[i].CHxCTL_f.IE = Enable;
        stc_llp_dma_codec_tx[i].DNSEQCTLx_f.DNSCNT = 1;
        stc_llp_dma_codec_tx[i].DNSEQCTLx_f.DOFFSET = 1;
    }
    stcDmaCfg.stcDmaChCfg.enLlpEn = Enable;
    stcDmaCfg.stcDmaChCfg.enLlpMd = LlpRunNow;
    stcDmaCfg.u32DmaLlp = (uint32_t)(&stc_llp_dma_codec_tx[0]);
    /* Enable DMA clock. */
    PWC_Fcg0PeriphClockCmd(I2S_CODEC_TX_DMA_CLK,Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);

    /* Enable DMA1. */
    //  DMA_Cmd(I2S_CODEC_TX_DMA_UNIT,Enable);
    /* Initialize DMA. */
    DMA_InitChannel(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH, &stcDmaCfg);
    DMA_SetTriggerSrc(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH, I2S_CODEC_TX_DMA_TRG);
    /* Enable DMA1 channel0. */
    DMA_ChannelCmd(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH,Enable);

    DMA_ClearIrqFlag(I2S_CODEC_TX_DMA_UNIT, I2S_CODEC_TX_DMA_CH, TrnCpltIrq);
//
//    stcIrqRegiConf.enIntSrc = INT_DMA1_BTC0;
//    stcIrqRegiConf.enIRQn = Int008_IRQn;
//    stcIrqRegiConf.pfnCallback =  REC_BTC0_CALLBACK;
//
//    enIrqRegistration(&stcIrqRegiConf);
//  NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);//Enable Interrupt
}

void i2s_codec_rx_callback(void)
{
    uint16_t i;

    flag_ab_codec = !flag_ab_codec;


    PORT_SetBits(INT_TIME_MEASURE_PORT, INT_TIME_MEASURE_PIN);
    if(flag_ab_codec) {
        for(i = 0; i < I2S_CODEC_BUFF_SIZE; i++) {
            //  au16Rectx[0].Data16bit[i] = au16Rec[0].Data16bit[i];
            i2s_codec_tx_buff[0][i] = i2s_codec_rx_buff[0][i];
        }
       // algorithm_run(i2s_mcu_tx_buff[0], i2s_mcu_tx_buff[0], I2S_CODEC_BUFF_SIZE);

    } else {
        for(i = 0; i < I2S_CODEC_BUFF_SIZE; i++) {
            // au16Rectx[1].Data16bit[i] = au16Rec[1].Data16bit[i];
            i2s_codec_tx_buff[1][i] = i2s_codec_rx_buff[1][i];
        }
        //algorithm_run(i2s_mcu_tx_buff[1],i2s_mcu_tx_buff[1], I2S_CODEC_BUFF_SIZE);
    }

    PORT_ResetBits(INT_TIME_MEASURE_PORT, INT_TIME_MEASURE_PIN);
}


void bsp_i2s_codec_rx_timer_cfg(void)
{
    stc_timera_base_init_t stcTimeraInit;
    stc_irq_regi_conf_t stcIrqRegiConf;
    stc_timera_orthogonal_coding_init_t Hw_Count_Trg_Cfg;
    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcTimeraInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(Hw_Count_Trg_Cfg);

    /* Configuration peripheral clock */
    PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIMA1, Enable);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);

    TIMERA_IrqCmd(M4_TMRA1, TimeraIrqOverflow, Disable);
    TIMERA_DeInit(M4_TMRA1);
    /* Configuration TIMERA compare pin */

    /* Configuration timera unit 1 base structure */
    stcTimeraInit.enClkDiv = TimeraPclkDiv1;
    stcTimeraInit.enCntMode = TimeraCountModeSawtoothWave;
    stcTimeraInit.enCntDir = TimeraCountDirUp;
    stcTimeraInit.enSyncStartupEn = Disable;
    stcTimeraInit.u16PeriodVal = I2S_CODEC_BUFF_SIZE-2;        //freq: 100Hz
    TIMERA_BaseInit(M4_TMRA1, &stcTimeraInit);


    /* Enable period count interrupt */
    TIMERA_IrqCmd(M4_TMRA1, TimeraIrqOverflow, Enable);
    /* Interrupt of timera unit 1 */
    stcIrqRegiConf.enIntSrc = INT_TMRA1_OVF;
    stcIrqRegiConf.enIRQn = Int011_IRQn;
    stcIrqRegiConf.pfnCallback = i2s_codec_rx_callback;
    enIrqRegistration(&stcIrqRegiConf);
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_12);
    NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
    TIMERA_SetCountTriggerSrc(I2S_CODEC_RX_DMA_TRG);

    Hw_Count_Trg_Cfg.enIncSpecifyEventTriggerEn = Enable;
    TIMERA_OrthogonalCodingInit(M4_TMRA1,&Hw_Count_Trg_Cfg);
    M4_TMRA1->BCSTR_f.START = Enable;
}


static void bsp_i2s_codec_cfg_init(uint32_t samp_rate, uint8_t samp_bit)
{
    stc_i2s_config_t stcI2sCfg;

    MEM_ZERO_STRUCT(stcI2sCfg);
    I2s_DeInit(I2S_CODEC_CH);
    stcI2sCfg.u32I2sInterClkFreq = bsp_i2s_get_clk_freq(I2S_CODEC_CH);
    stcI2sCfg.enStandrad = Std_Philips;
    stcI2sCfg.enMode = I2sSlave;
    stcI2sCfg.enChanelLen = I2s_ChLen_32Bit;
    stcI2sCfg.enDataBits = (en_i2s_data_len_t)samp_bit;
    stcI2sCfg.u32AudioFreq = samp_rate;
    stcI2sCfg.enMcoOutEn =Disable;
    stcI2sCfg.enExckEn = Disable;
    stcI2sCfg.enFullDuplexMode = I2s_FullDuplex;

    I2s_Init(I2S_CODEC_CH, &stcI2sCfg);
    I2S_CODEC_CH->CTRL_f.DUPLEX = 1;
}

void I2S1_ERROR_Callback(void)
{
    I2S_FuncCmd(I2S_CODEC_CH, RxEn, Disable);
	I2S_FuncCmd(I2S_CODEC_CH, TxEn, Disable);
	printf("i2s_rx_err:%x\r\n",I2S_CODEC_CH->ER);
    while((I2S_CODEC_CH->ER & 0x03) !=0)
    {
        I2S_CODEC_CH->ER = 3;
    }    
//    printf("I2S error\r\n");   
//	if(app_sta.rec_state != REC_IDLE){
	I2S_FuncCmd(I2S_CODEC_CH, RxEn, Enable);
	
	
    I2S_FuncCmd(I2S_CODEC_CH, TxEn, Enable);
}

//算法挂接I2S输入DMA处理
static void bsp_i2s_input_alg_cfg(uint32_t samp_rate, uint8_t samp_bit)
{
    memset(i2s_mcu_tx_buff,0,sizeof(i2s_mcu_tx_buff));
    memset(i2s_codec_tx_buff,0,sizeof(i2s_codec_tx_buff));
    memset(i2s_codec_rx_buff,0,sizeof(i2s_codec_rx_buff));

    //bsp_i2s_mcu_tx_dma_config(i2s_mcu_tx_buff);
    //bsp_i2s_mcu_rx_dma_config(i2s_codec_tx_buff);
    //bsp_i2s_mcu_cfg_init(samp_rate, samp_bit);

    bsp_i2s_codec_tx_dma_config(i2s_codec_tx_buff);
    bsp_i2s_codec_rx_dma_config(i2s_codec_rx_buff);
    bsp_i2s_codec_rx_timer_cfg();

    bsp_i2s_codec_cfg_init(samp_rate, samp_bit);
    stc_irq_regi_conf_t stcIrqRegiConf;
    MEM_ZERO_STRUCT(stcIrqRegiConf);

    stcIrqRegiConf.enIntSrc = INT_I2S1_ERRIRQOUT;
    stcIrqRegiConf.enIRQn = Int009_IRQn;
    stcIrqRegiConf.pfnCallback =  I2S1_ERROR_Callback;   
    
    enIrqRegistration(&stcIrqRegiConf);
	NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);//Enable Interrupt
}

//算法挂接I2S输出DMA处理
static void bsp_i2s_output_alg_cfg(uint32_t samp_rate, uint8_t samp_bit)
{
    memset(i2s_mcu_rx_buff,0,sizeof(i2s_mcu_rx_buff));
    memset(i2s_codec_tx_buff,0,sizeof(i2s_codec_tx_buff));
    memset(i2s_codec_rx_buff,0,sizeof(i2s_codec_rx_buff));

    bsp_i2s_mcu_tx_dma_config(i2s_codec_rx_buff);
    bsp_i2s_mcu_rx_dma_config(i2s_mcu_rx_buff);
    bsp_i2s_mcu_rx_timer_cfg();
    bsp_i2s_mcu_cfg_init(samp_rate, samp_bit);

    bsp_i2s_codec_tx_dma_config(i2s_codec_tx_buff);
    bsp_i2s_codec_rx_dma_config(i2s_codec_rx_buff);
    bsp_i2s_codec_cfg_init(samp_rate, samp_bit);
}

//0：输入输出禁止，1：仅输入，2：仅输出，3：输入输出使能
static void bsp_i2s_enable(uint8_t en_flag)
{
#if 0
    switch(en_flag) {
        case I2S_MODE_DISABLE:
            I2S_FuncCmd(I2S_CODEC_CH, RxEn, Disable);
            I2S_FuncCmd(I2S_CODEC_CH, TxEn, Disable);
            //I2S_FuncCmd(I2S_MCU_CH,   RxEn, Disable);
           // I2S_FuncCmd(I2S_MCU_CH,   TxEn, Disable);
            //DMA_Cmd(I2S_MCU_TX_DMA_UNIT,    Disable);
           // DMA_Cmd(I2S_MCU_RX_DMA_UNIT,    Disable);
            DMA_Cmd(I2S_CODEC_TX_DMA_UNIT,  Disable);
            DMA_Cmd(I2S_CODEC_RX_DMA_UNIT,  Disable);
            TIMERA_IrqCmd(M4_TMRA1, TimeraIrqOverflow, Disable);
            //TIMERA_IrqCmd(M4_TMRA4, TimeraIrqOverflow, Disable);
            M4_TMRA1->BCSTR_f.START = Disable;
            //M4_TMRA4->BCSTR_f.START = Disable;
            break;
        case I2S_MODE_INPUT:
            I2S_FuncCmd(I2S_CODEC_CH, RxEn, Enable);
            I2S_FuncCmd(I2S_CODEC_CH, TxEn, Disable);
            I2S_FuncCmd(I2S_MCU_CH,   RxEn, Disable);
            I2S_FuncCmd(I2S_MCU_CH,   TxEn, Enable);
            DMA_Cmd(I2S_MCU_TX_DMA_UNIT,    Enable);
            DMA_Cmd(I2S_MCU_RX_DMA_UNIT,    Disable);
            DMA_Cmd(I2S_CODEC_TX_DMA_UNIT,  Disable);
            DMA_Cmd(I2S_CODEC_RX_DMA_UNIT,  Enable);
            //  M4_TMRA1->BCSTR_f.START = Enable;
            //  M4_TMRA4->BCSTR_f.START = Enable;
            break;
        case I2S_MODE_OUTPUT:
            I2S_FuncCmd(I2S_CODEC_CH, RxEn, Disable);
            I2S_FuncCmd(I2S_CODEC_CH, TxEn, Enable);
            I2S_FuncCmd(I2S_MCU_CH,   RxEn, Enable);
            I2S_FuncCmd(I2S_MCU_CH,   TxEn, Disable);
            DMA_Cmd(I2S_MCU_TX_DMA_UNIT,    Disable);
            DMA_Cmd(I2S_MCU_RX_DMA_UNIT,    Enable);
            DMA_Cmd(I2S_CODEC_TX_DMA_UNIT,  Enable);
            DMA_Cmd(I2S_CODEC_RX_DMA_UNIT,  Disable);
            //  M4_TMRA1->BCSTR_f.START = Enable;
            //  M4_TMRA4->BCSTR_f.START = Enable;
            break;
        case I2S_MODE_FULL:
            I2S_FuncCmd(I2S_CODEC_CH, RxEn, Enable);
            I2S_FuncCmd(I2S_CODEC_CH, TxEn, Enable);
            //I2S_FuncCmd(I2S_MCU_CH,   RxEn, Enable);
           // I2S_FuncCmd(I2S_MCU_CH,   TxEn, Enable);
          //  DMA_Cmd(I2S_MCU_TX_DMA_UNIT,    Enable);
          //  DMA_Cmd(I2S_MCU_RX_DMA_UNIT,    Enable);
            DMA_Cmd(I2S_CODEC_TX_DMA_UNIT,  Enable);
            DMA_Cmd(I2S_CODEC_RX_DMA_UNIT,  Enable);
            //  M4_TMRA1->BCSTR_f.START = Enable;
            //  M4_TMRA4->BCSTR_f.START = Enable;
            break;
    }
#endif    
}
static const uint32_t bsp_i2s_samp_rate[] = {I2S_AudioFreq_8k, I2S_AudioFreq_16k, I2S_AudioFreq_22k,
                                             I2S_AudioFreq_32k,I2S_AudioFreq_44k, I2S_AudioFreq_48k,
                                             88200, I2S_AudioFreq_96k
                                            };
static const uint8_t bsp_i2s_samp_bit[] = {I2s_DataLen_16Bit, I2s_DataLen_24Bit, I2s_DataLen_32Bit};
#if 0
uint8_t i2s_cfg_ack(bsp_i2s_cfg_typedef *cfg)
{
    if(cfg->alg_type > ALG_TYPE_OUT) return 1;
    if(cfg->mode > I2S_MODE_FULL) return 1;
    if(cfg->samp_bit > SAMP_BIT_32) return 1;
    if(cfg->samp_rate > SAMP_RATE_96K) return 1;

    return 0;
}
#endif

void bsp_i2s_cfg(bsp_i2s_cfg_typedef *cfg)
{
//    if(i2s_cfg_ack(cfg)) return;

//    bsp_i2s_enable(I2S_MODE_DISABLE);

    //if(cfg->alg_type == ALG_TYPE_IN) {
    bsp_i2s_input_alg_cfg(I2S_AudioFreq_48k, I2s_DataLen_24Bit);
    //} else if(cfg->alg_type == ALG_TYPE_OUT) {
    //    bsp_i2s_output_alg_cfg(bsp_i2s_samp_rate[cfg->samp_rate], bsp_i2s_samp_bit[cfg->samp_bit]);
    //}

//    bsp_i2s_enable(I2S_MODE_FULL);
    //while(1){
    //    if(I2S_GetStatus(I2S_CODEC_CH,TxBufEmptFlag))
    //        I2S_SendData(I2S_CODEC_CH, 0x112233);
    //}
    flag_ab_codec = 0;
    flag_ab_mcu = 0;
}

void bsp_i2s_init(void)
{
    bsp_i2s_measure_gpio();
   // bsp_i2s_mcu_gpio_init();
    bsp_i2s_codec_gpio_init();

}
